#                                                   #								
# bash functions and parameters for debugging       #
# At Consulting (c)                                 #
# MMartynov@vrn.beeline.ru                          #
#                                                   #
#                                                   #

source $HOME/.profile &>/dev/null
umask 0002

##########################################################
# CHECK ENVIRONMENT
##########################################################

if [ -z "$OPENARS_HOME" ]; then
    echo "please, define and export OPENARS_HOME in your .progile. exit 1."
    exit 1
fi

if [ ! -d "$OPENARS_HOME" ]; then
    echo "not find OPENARS_HOME directory: $OPENARS_HOME. exit 1."
    exit 1
fi

[ ! -d "$OPENARS_HOME/logs" ] && mkdir $OPENARS_HOME/logs 

##########################################################
# DECLARATION
##########################################################
 
# initially (for initializing other variable)
SCRIPT=$0
while [ -h "$SCRIPT" ]; do SCRIPT=`ls -l "$SCRIPT" | awk '{print $NF}'`; done 
SCRIPT_BASENAME=`basename $SCRIPT`
SCRIPT_DIRNAME=`dirname $SCRIPT`
echo $SCRIPT_DIRNAME | grep ^/ &>/dev/null
[ $? -ne 0 ] && SCRIPT_DIRNAME=`echo $SCRIPT_DIRNAME | sed s!^!$PWD/!`

#public read (possible use in your scripts)
PRJDIR=$SCRIPT_DIRNAME
INDIR=$PRJDIR/input
OUTDIR=$PRJDIR/output
TEMPDIR=$PRJDIR/temp/$$;

# public edit (possible change in your scripts)
DEBUG_LEVEL=1
    # 1: INF, WARN, ERR, STDERR
    # 2: STDOUT, more INF
    # 3: not rm $TEMPDIR
INFILE=$INDIR/$SCRIPT_BASENAME.in 
OUTFILE=$OUTDIR/$SCRIPT_BASENAME.out

# private (only for use in this file)
_CONFFILE=$OPENARS_HOME/conf/scripts.xml
_LOGFILE=$OPENARS_HOME/logs/all_scripts.log
_ERRFILE=$_LOGFILE
_SSH_OPEN=$TEMPDIR/ssh_open.lst   # counter open_ssh-connects
_SSH_CLOSE=$TEMPDIR/ssh_close.lst # counter close_ssh-connects
_STDOUT_TMP=$TEMPDIR/stdout.tmp
_STDERR_TMP=$TEMPDIR/stderr.tmp
_SCRIPT_ID=`perl -e 'print time' | cut -c5-10`$$


##########################################################
# INITIALIZATION AND PRIVATE FUNCTIONS
##########################################################

[ -z "$_INCLUDE_CONF" ] && source $OPENARS_HOME/common/conf.h
main_setenv

function text100() {
  text=`echo $text | sed -e 's/^\(.\{100\}\).*$/\1\ \.\.\./'`; 
}

#check run-type (cron, tty)
script_line=`cat $_CONFFILE | sed -n -e '/^\ *<script\ /p' | grep sname=\"$SCRIPT_BASENAME\" | head -1`
#[ -z "$script_line"] && ERR
run_type=`echo "$script_line" | get_xmlparam "type"`
    tty -s #check terminal
    tty_code=$?
    if [ "$tty_code" -eq 0 -a "$run_type" = cron ]; then
	echo "error: only crontab! exit."
	exit 1;
    fi
    if [ "$tty_code" -eq 1 -a "$run_type" = tty ]; then
	echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` START `basename $0` [0] local \"PID=$$ LOGNAME=$LOGNAME ERROR: run only terminal! exit 1\"" >> $_LOGFILE
	exit 1;
    fi

#check user-permission for run script
# ....

#check: this script already run
pcount=`ps -ef | grep $SCRIPT_BASENAME | egrep -v "grep|$$|$PPID" | wc -l`
if [ "$pcount" -gt 0 ]; then
        echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` START `basename $0` [0] local \"PID=$$ LOGNAME=$LOGNAME ERROR: this script already run. exit 1\"" >> $_LOGFILE
        exit 1;
fi

#create necessary directory
[ ! -d $PRJDIR/input ] && mkdir -p $PRJDIR/input &>/dev/null
[ ! -d $PRJDIR/output ] && mkdir -p $PRJDIR/output &>/dev/null
[ ! -d $PRJDIR/temp ] && mkdir -p $PRJDIR/temp &>/dev/null
[ ! -w $PRJDIR/input -o ! -w $PRJDIR/output -o ! -w $PRJDIR/temp ] && exit 65 
mkdir -p $TEMPDIR

exec 1>>$_STDOUT_TMP
exec 2>>$_STDERR_TMP

#startline 
echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` START `basename $0` [1] local \"PID=$$ LOGNAME=$LOGNAME\"" >> $_LOGFILE

cd $PRJDIR

function trap_signal_killchild()
{
    function fill_childlist() {
	list=`pgrep -P $1`
	for i in $list
	do
	    childlist="$childlist $i"
	    fill_childlist $i
	done
    }
    childlist=""
    fill_childlist $$
    for i in $childlist
    do	
     chname=`pargs $i 2>/dev/null | grep 'argv\[0\]' | awk '{print $2}'`
     charg=`pargs $i 2>/dev/null | grep 'argv\[1\]' | awk '{print $2}'`
     [ "$chname" = "ssh" ] && echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` WARN `basename $0` [${BASH_LINENO[0]}] local \"timelimit. kill $chname $charg\""
    done
    kill -9 $childlist &>/dev/null
} >> $_LOGFILE

function trap_stdout()
{
 while read text
 do
  text100    
  echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` STDOUT `basename $0` [0] local \"$text\"";
 done < $_STDOUT_TMP
 >$_STDOUT_TMP
} >> $_LOGFILE

function trap_stderr()
{
 while read text
 do
  text100
  echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` STDERR `basename $0` [0] local \"$text\"";
 done < $_STDERR_TMP
 >$_STDERR_TMP
} >> $_LOGFILE

function trap_exit()
{
 local exit_code=$?
 sleep 1
 while read text
 do
  text100
  echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` STDERR `basename $0` [0] local \"$text\"";
 done < $_STDERR_TMP
 >$_STDERR_TMP
 while read text
 do
  text100
  [ "$DEBUG_LEVEL" -ge 2 ] && echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` STDOUT `basename $0` [0] local \"$text\"";
 done < $_STDOUT_TMP
 >$_STDOUT_TMP
 ssh_open=`cat $_SSH_OPEN 2>/dev/null | wc -l | awk '{print $1}'`
 ssh_close=`cat $_SSH_CLOSE 2>/dev/null | wc -l | awk '{print $1}'`
 echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` STOP `basename $0` [${BASH_LINENO[0]}] local \
 \"exit_code=$exit_code DEBUG_LEVEL=$DEBUG_LEVEL ssh_open=$ssh_open ssh_close=$ssh_close\"";
 cd $PRJDIR; [ "$DEBUG_LEVEL" -lt 3 -a -d "$TEMPDIR" ] && rm -r $TEMPDIR
} >> $_LOGFILE

#set -o errtrace
trap 'trap_stderr' ERR
trap 'trap_exit' EXIT
trap 'trap_signal_killchild' 14

##########################################################
# PUBLIC FUNCTIONS
##########################################################

#use: INF "text"  
function INF() {
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` INF `basename $0` [${BASH_LINENO[0]}] local \"$1\""
} >> $_LOGFILE

#use: WARN "text"  
function WARN() {
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` WARN `basename $0` [${BASH_LINENO[0]}] local \"$1\""
} >> $_LOGFILE

#use: ERR "text"
function ERR() {
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` ERR `basename $0` [${BASH_LINENO[0]}] local \"$1\""
} >> $_LOGFILE

#use: REPORT "text (filename)"
function REPORT() {
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` REPORT `basename $0` [${BASH_LINENO[0]}] local \"$1\""
} >> $_LOGFILE

#use: BREPORT "text (filename)"
function BREPORT() {
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` BREPORT `basename $0` [${BASH_LINENO[0]}] local \"$1\""
} >> $_LOGFILE

#use: BREPORT "text (filename)"
function BREPORT() {
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` BREPORT `basename $0` [${BASH_LINENO[0]}] local \"$1\""
} >> $_LOGFILE

#use: ECHO "text"
function ECHO() {
    echo "$@" > /dev/tty
}

#use SSH <connect> "commands" <varname_result>
function SSH() {
    tmpdir="$TEMPDIR/ssh_${BASH_LINENO[0]}"
    mkdir -p $tmpdir
    host=`echo $1 | sed s/^.*@//`
    echo "$host" >> $_SSH_OPEN
    [ $DEBUG_LEVEL -ge 2 ] && echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` INF `basename $0` [${BASH_LINENO[0]}] local \"open ssh-connect $host\""
    res=`ssh $1 "$2" 2>>"$tmpdir/stderr_$host.tmp"` 
    exit_code=$?
    if [ "$exit_code" -ne 0 ]; then
	  echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` WARN `basename $0` [${BASH_LINENO[0]}] local \"Error ssh-connect or ssh-commands on $host: exit_code=$exit_code\""
    fi
    [ ! -z "$3" ] && eval $3="\"$res\""
    cat "$tmpdir/stderr_$host.tmp" | grep -v ^$ | grep -v "^|" | \
	sed s/^/"$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` STDERR `basename $0` [0] $host \""/ | sed s/$/\"/ 
    [ $DEBUG_LEVEL -ge 2 ] && echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` INF `basename $0` [${BASH_LINENO[0]}] local \"close ssh-connect $host\""
    echo "$host" >> $_SSH_CLOSE
    return $exit_code
} >> $_LOGFILE

function WAIT() {
    timelimit=$1    
    mypids=`pgrep -P $$`
    [ -z "$mypids" ] && return 
    echo "$_SCRIPT_ID `date +'%Y.%m.%d %H:%M:%S'` INF `basename $0` [${BASH_LINENO[0]}] local \"wait backgrounds processes (timelimit = $1 sec) ...\""
    if [ ! -z $timelimit ]; then # start control process
     sleep $timelimit && kill -s 14 $$ &
    fi
    wait $mypids
    kill $! &>/dev/null # kill control_process
} >> $_LOGFILE
